﻿import {colorHelper} from "@/utils/colorHelper";

export const buildChart = function (myChart, data, columnFields, rowFields, options) {
  //一级维度
  var dimensionField = columnFields.find(function (d) {
    return d.slaveType === 0;
  });
  var measureField = rowFields.find(function (d) {
    return d.slaveType === 1;
  });
  //呈现方向判定
  var direction = "horizon";//横向
  if (!dimensionField) {
    direction = "vertical";//纵向
    dimensionField = rowFields.find(function (d) {
      return d.slaveType === 0;
    });
    measureField = columnFields.find(function (d) {
      return d.slaveType === 1;
    });
  }
  if (!dimensionField || !measureField || !data.length) {
    return;
  }
  data = Enumerable.from(data).orderBy(function (d) {
    return d[dimensionField.name];
  }).toArray();
  var categories = data.map(function (d) {
    return d[dimensionField.name];
  });
  var config = options.chartConfig;
  //图表间距
  var padding = [30, 10, 15, 10];
  if (config.chartPadding && config.chartPadding != '') {
    var arrayPadding = config.chartPadding.split(' ');
    if (arrayPadding.length >= 4) {
      padding = arrayPadding.map(function (d) {
        return parseInt(d);
      });
    }
  }
  //轴文字样式
  var axis_nameTextStyle = {
    color: config.axisStyle.fontColor,
    fontSize: config.axisStyle.fontSize,
    fontFamily: config.axisStyle.fontFamily
  }
  //数据条标签配置
  var labelOption = {
    show: config.textStyle["display"] !== "none",
    distance: 5,
    align: "left",
    verticalAlign: "middle",
    fontSize: config.textStyle["font-size"],
    fontFamily: config.textStyle["font-family"],
    color: config.textStyle["fill"]
  };
  const option_chart = {
    color: config.MultiColors,
    legend: {
      data: [],
      textStyle: axis_nameTextStyle,
      show: config.showLegend == undefined ? true : config.showLegend,
      type: 'scroll',
      pageIconColor: config.axisStyle.fontColor,
      pageTextStyle: axis_nameTextStyle,
      itemWidth: 14,
      itemHeight: 14
    },
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'cross',
        label: {
          color: colorHelper.invert(axis_nameTextStyle.color),
          backgroundColor: axis_nameTextStyle.color
        }
      }
    },
    calculable: true,
    grid: [{
      top: (config.showLegend == undefined || config.showLegend) ? 20 + padding[0] : padding[0],
      left: padding[3],
      bottom: padding[2],
      right: padding[1],
      containLabel: true
    }],
    series: [],
    others: {
      dimensionField: dimensionField,
      measureField: measureField,
      data: data,
      labelOption: labelOption,
      config: config,
      stackType: options.stackType,
      direction: direction,
      labelFormater: config.labelFormater
    }
  };
  config.legendPosition = config.legendPosition || "top";
  if (config.legendPosition == "left") {
    option_chart.legend.x = "left";
  } else if (config.legendPosition == "right") {
    option_chart.legend.x = "right";
  }
  //轴线配置
  const axis_axisLine = {
    lineStyle: {
      color: config.axisStyle.tickColor
    },
    show: config.showAxisLine == undefined ? true : config.showAxisLine
  };
  //定义轴方向
  if (direction === "horizon") {
    labelOption.position = "top";
    option_chart.xAxis = [{
      type: 'category',
      axisTick: {show: false},
      data: categories,
      name: config.xAxisLabelRotate ? "" : dimensionField.name,
      nameTextStyle: axis_nameTextStyle,
      axisLine: axis_axisLine,
      axisLabel: {
        color: axis_nameTextStyle.color,
        fontSize: axis_nameTextStyle.fontSize,
        fontFamily: axis_nameTextStyle.fontFamily,
        rotate: config.xAxisLabelRotate != undefined ? config.xAxisLabelRotate : 0,
        show: config.showAxisLabel ? config.showAxisLabel.category : true
      },
      nameLocation: "middle",
      nameGap: config.axisStyle.fontSize * 1.8,
      gridIndex: 0
    }];
    if (config.xAxisName) {
      if (config.xAxisName.show) {
        if (config.xAxisName.name) {
          option_chart.xAxis[0].name = config.xAxisName.name;
        }
      } else {
        option_chart.xAxis[0].name = "";
      }
    }

    option_chart.yAxis = [{
      type: 'value',
      name: measureField.name,
      nameTextStyle: axis_nameTextStyle,
      axisLine: axis_axisLine,
      axisTick: axis_axisLine,
      splitLine: {
        show: config.showSplitLine && (config.splitLineMode == undefined || config.splitLineMode == "all" || config.splitLineMode == "left"),
        lineStyle: {
          color: config.axisStyle.tickColor
        }
      },
      axisLabel: {
        color: axis_nameTextStyle.color,
        fontSize: axis_nameTextStyle.fontSize,
        fontFamily: axis_nameTextStyle.fontFamily,
        show: config.showAxisLabel ? config.showAxisLabel.value : true
      },
      gridIndex: 0
    }, {
      type: 'value',
      name: "百分比",
      nameTextStyle: axis_nameTextStyle,
      axisLine: axis_axisLine,
      axisTick: axis_axisLine,
      splitLine: {
        show: config.showSplitLine && (config.splitLineMode == undefined || config.splitLineMode == "all" || config.splitLineMode == "right"),
        lineStyle: {
          color: config.axisStyle.tickColor
        }
      },
      axisLabel: {
        color: axis_nameTextStyle.color,
        fontSize: axis_nameTextStyle.fontSize,
        fontFamily: axis_nameTextStyle.fontFamily,
        show: config.showAxisLabel ? config.showAxisLabel.value2 : true,
        formatter: '{value} %'
      },
      gridIndex: 0
    }];
    if (config.yAxisName) {
      if (config.yAxisName.show) {
        if (config.yAxisName.name) {
          option_chart.yAxis[0].name = config.yAxisName.name;
        }
      } else {
        option_chart.yAxis[0].name = "";
      }
    }
    if (config.yAxisName2) {
      if (config.yAxisName2.show) {
        if (config.yAxisName2.name) {
          option_chart.yAxis[1].name = config.yAxisName2.name;
        }
      } else {
        option_chart.yAxis[1].name = "";
      }
    }
    if (config.valueRange) {
      if (!isNaN(Number(config.valueRange.min)) && config.valueRange.min != null && config.valueRange.min.length) {
        option_chart.yAxis[0].min = Number(config.valueRange.min);
      }
      if (!isNaN(Number(config.valueRange.max)) && config.valueRange.max != null && config.valueRange.max.length) {
        option_chart.yAxis[0].max = Number(config.valueRange.max);
      }
    }
    if (config.valueRange2) {
      if (!isNaN(Number(config.valueRange2.min)) && config.valueRange2.min != null && config.valueRange2.min.length) {
        option_chart.yAxis[1].min = Number(config.valueRange2.min);
      }
      if (!isNaN(Number(config.valueRange2.max)) && config.valueRange2.max != null && config.valueRange2.max.length) {
        option_chart.yAxis[1].max = Number(config.valueRange2.max);
      }
    }
  } else {
    labelOption.position = "insideRight";
    option_chart.xAxis = [{
      type: 'value',
      name: measureField.name,
      nameTextStyle: axis_nameTextStyle,
      axisLine: axis_axisLine,
      axisTick: axis_axisLine,
      axisLabel: {
        color: axis_nameTextStyle.color,
        fontSize: axis_nameTextStyle.fontSize,
        fontFamily: axis_nameTextStyle.fontFamily,
        show: config.showAxisLabel ? config.showAxisLabel.value : true
      },
      splitLine: {
        show: config.showSplitLine && (config.splitLineMode == undefined || config.splitLineMode == "all" || config.splitLineMode == "left"),
        lineStyle: {
          color: config.axisStyle.tickColor
        }
      },
      nameLocation: "middle",
      nameGap: config.axisStyle.fontSize * 1.8,
      gridIndex: 0
    }, {
      type: 'value',
      name: "百分比",
      nameTextStyle: axis_nameTextStyle,
      axisLine: axis_axisLine,
      axisTick: axis_axisLine,
      splitLine: {
        show: config.showSplitLine && (config.splitLineMode == undefined || config.splitLineMode == "all" || config.splitLineMode == "left"),
        lineStyle: {
          color: config.axisStyle.tickColor
        }
      },
      axisLabel: {
        color: axis_nameTextStyle.color,
        fontSize: axis_nameTextStyle.fontSize,
        fontFamily: axis_nameTextStyle.fontFamily,
        show: config.showAxisLabel ? config.showAxisLabel.value2 : true,
        formatter: '{value} %'
      },
      nameLocation: "middle",
      nameGap: config.axisStyle.fontSize * 1.8,
      gridIndex: 0
    }];
    if (config.yAxisName) {
      if (config.yAxisName.show) {
        if (config.yAxisName.name) {
          option_chart.xAxis[0].name = config.yAxisName.name;
        }
      } else {
        option_chart.xAxis[0].name = "";
      }
    }
    if (config.yAxisName2) {
      if (config.yAxisName2.show) {
        if (config.yAxisName2.name) {
          option_chart.xAxis[1].name = config.yAxisName2.name;
        }
      } else {
        option_chart.xAxis[1].name = "";
      }
    }
    if (config.valueRange) {
      if (!isNaN(Number(config.valueRange.min)) && config.valueRange.min != null && config.valueRange.min.length) {
        option_chart.xAxis[0].min = Number(config.valueRange.min);
      }
      if (!isNaN(Number(config.valueRange.max)) && config.valueRange.max != null && config.valueRange.max.length) {
        option_chart.xAxis[0].max = Number(config.valueRange.max);
      }
    }
    if (config.valueRange2) {
      if (!isNaN(Number(config.valueRange2.min)) && config.valueRange2.min != null && config.valueRange2.min.length) {
        option_chart.xAxis[1].min = Number(config.valueRange2.min);
      }
      if (!isNaN(Number(config.valueRange2.max)) && config.valueRange2.max != null && config.valueRange2.max.length) {
        option_chart.xAxis[1].max = Number(config.valueRange2.max);
      }
    }
    option_chart.yAxis = [{
      type: 'category',
      axisTick: {show: false},
      data: categories,
      name: config.xAxisLabelRotate ? "" : dimensionField.name,
      nameTextStyle: axis_nameTextStyle,
      axisLine: axis_axisLine,
      axisLabel: {
        color: axis_nameTextStyle.color,
        fontSize: axis_nameTextStyle.fontSize,
        fontFamily: axis_nameTextStyle.fontFamily,
        rotate: config.xAxisLabelRotate != undefined ? config.xAxisLabelRotate : 0,
        show: config.showAxisLabel ? config.showAxisLabel.category : true
      },
      nameLocation: "start",
      inverse: true,
      gridIndex: 0
    }];
    if (config.xAxisName) {
      if (config.xAxisName.show) {
        if (config.xAxisName.name) {
          option_chart.yAxis[0].name = config.xAxisName.name;
        }
      } else {
        option_chart.yAxis[0].name = "";
      }
    }
  }
  var serie1 = {
    name: "本期",
    type: 'line',
    label: labelOption,
    data: [],
    smooth: config.lineSmooth
  }
  option_chart.series.push(serie1);
  option_chart.legend.data.push("本期");
  if (config.fillArea == 1) {
    serie1.areaStyle = {}
  }
  serie1.data = data.map(function (d) {
    return d[measureField.name];
  });
  var serie2 = {
    name: "同期",
    type: 'line',
    label: labelOption,
    data: [],
    smooth: config.lineSmooth
  }
  option_chart.series.push(serie2);
  option_chart.legend.data.push("同期");
  if (config.fillArea == 1) {
    serie2.areaStyle = {}
  }
  serie2.data = data.map(function (d) {
    return d.YoYValue == undefined ? 0 : d[measureField.name] - d.YoYValue;
  });
  var serie3 = {
    name: "同比增长率",
    type: 'line',
    label: labelOption,
    data: [],
    smooth: config.lineSmooth
  }
  option_chart.series.push(serie3);
  option_chart.legend.data.push("同比增长率");
  if (config.fillArea == 1) {
    serie3.areaStyle = {}
  }
  if (direction === "horizon") {
    serie3.yAxisIndex = 1;
  } else {
    serie3.xAxisIndex = 1;
  }
  serie3.data = data.map(function (d) {
    return d.YoYRate;
  });
  var serie4 = {
    name: "环比增长率",
    type: 'line',
    label: labelOption,
    data: [],
    smooth: config.lineSmooth
  }
  option_chart.series.push(serie4);
  option_chart.legend.data.push("环比增长率");
  if (config.fillArea == 1) {
    serie4.areaStyle = {}
  }
  serie4.data = data.map(function (d) {
    return d.QoQRate;
  });
  if (direction === "horizon") {
    serie4.yAxisIndex = 1;
  } else {
    serie4.xAxisIndex = 1;
  }
  const chartInstance = new chart(myChart, option_chart);
  return chartInstance;
}
var chart = function (myChart, opt) {
  const setOption = function (opt) {
    chart_opt = $.extend(true, chart_opt, opt);
    chart_opt.series.forEach(function (d) {
      d.label.formatter = labelFormatter;
    });
    myChart.setOption(chart_opt);
  };
  const self = this;
  var config = opt.others.config;
  var labelOption = opt.others.labelOption;
  delete opt.others.config;
  delete opt.others.labelOption;
  var _labelFormater = opt.others.labelFormater || "name:value";
  var chart_opt = {
    tooltip: {
      formatter: function (args) {
        /*args[0]
         $vars: (3) ["seriesName", "name", "value"]
            axisDim: "x"
            axisId: "年(订单日期)0"
            axisIndex: 0
            axisType: "xAxis.category"
            axisValue: "2017"
            axisValueLabel: "2017"
            color: "#B07AA1"
            componentIndex: 16
            componentSubType: "line"
            componentType: "series"
            data: 101248.43399999998
            dataIndex: 3
            dataType: undefined
            marker: "<span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:#B07AA1;"></span>"
            name: "2017"
            seriesId: "椅子0"
            seriesIndex: 16
            seriesName: "椅子"
            seriesType: "line"
            value: 101248.43399999998
         */
        var tips = "";
        if (Array.isArray(args)) {
          if (args.length > 10) {
            opt.tooltip.trigger = "item";
            setOption(opt);
            return tips;
          }
          var arg0 = args[0];
          tips += opt.others.dimensionField.name + ":" + arg0.name + "<br/>";
          args.forEach(function (arg, idx) {
            if (!isNaN(Number(arg.value))) {
              tips += arg.marker;
              tips += arg.seriesName + ":";
              if (arg.seriesName == "同期" || arg.seriesName == "本期") {
                tips += Number(arg.value).toMeasureFormart(opt.others.measureField.numberFormat);
              } else if (arg.seriesName.includes("增长率")) {
                tips += Number(arg.value).toFixed(2) + "%";
              }
              if (idx != args.length - 1) {
                tips += "<br/>";
              }
            }
          });

        }
        return tips;
      }
    }

  }
  var labelFormatter = function (args) {

    var result = _labelFormater.replace("name", args.seriesName);
    if (args.seriesName.includes("增长率")) {
      result = result.replace("value", Number(args.value).toFixed(2) + "%");
    } else {
      result = result.replace("value", args.value.toMeasureFormart(chart_opt.others.measureField.numberFormat));
    }
    return result;
  }
    //响应点击事件
  myChart.on("click", function (args) {
    if (args.componentType === "series") {
      var calldata = [{
        field: chart_opt.others.dimensionField,
        value: [args.name]
      }];
      if (self.onselected) {
        self.onselected(calldata);
      }
    }
  });
  if (opt) {
    setOption(opt);
  }
  this.setOption = setOption;
  this.update = function (data) {
    var dimensionField = chart_opt.others.dimensionField;
    var measureField = chart_opt.others.measureField;
    var direction = chart_opt.others.direction;
    data = Enumerable.from(data).orderBy(function (d) {
      return d[chart_opt.others.dimensionField.name];
    }).toArray();
    var categories = data.map(function (d) {
      return d[dimensionField.name];
    });
    //按二级维度分组

    chart_opt.series = [];

    var serie1 = {
      name: "本期",
      type: 'line',
      label: labelOption,
      data: [],
      smooth: config.lineSmooth
    }
    option_chart.series.push(serie1);
    option_chart.legend.data.push("本期");
    if (config.fillArea == 1) {
      serie1.areaStyle = {}
    }
    serie1.data = data.map(function (d) {
      return d[measureField.name];
    });
    var serie2 = {
      name: "同期",
      type: 'line',
      label: labelOption,
      data: [],
      smooth: config.lineSmooth
    }
    option_chart.series.push(serie2);
    option_chart.legend.data.push("同期");
    if (config.fillArea == 1) {
      serie2.areaStyle = {}
    }
    serie2.data = data.map(function (d) {
      return d.YoYValue == undefined ? 0 : d[measureField.name] - d.YoYValue;
    });
    var serie3 = {
      name: "同比增长率",
      type: 'line',
      label: labelOption,
      data: [],
      smooth: config.lineSmooth
    }
    option_chart.series.push(serie3);
    option_chart.legend.data.push("同比增长率");
    if (config.fillArea == 1) {
      serie3.areaStyle = {}
    }
    if (direction === "horizon") {
      serie3.yAxisIndex = 1;
    } else {
      serie3.xAxisIndex = 1;
    }
    serie3.data = data.map(function (d) {
      return d.YoYRate;
    });
    var serie4 = {
      name: "环比增长率",
      type: 'line',
      label: labelOption,
      data: [],
      smooth: config.lineSmooth
    }
    option_chart.series.push(serie4);
    option_chart.legend.data.push("环比增长率");
    if (config.fillArea == 1) {
      serie4.areaStyle = {}
    }
    if (direction === "horizon") {
      serie4.yAxisIndex = 1;
    } else {
      serie4.xAxisIndex = 1;
    }
    serie4.data = data.map(function (d) {
      return d.QoQRate;
    });
    var cAxis = chart_opt.xAxis.find(function (d) {
      return d.type == "category";
    });
    if (!cAxis) {
      cAxis = chart_opt.yAxis.find(function (d) {
        return d.type == "category";
      });
    }
    cAxis.data = categories;
    chart_opt.others.categories = categories;
    setOption(chart_opt);
  }
}

